package com.norns.torque.utils;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidParameterException;
import java.util.Locale;

public class DataConversion {
    /**
     * 判断奇数或偶数，位运算，最后一位是1则为奇数，为0是偶数
     *
     * @param num
     * @return
     */
    public static int isOdd(int num) {
        return num & 0x1;
    }

    /**
     * 将int转成byte
     *
     * @param number
     * @return
     */
    public static byte intToByte(int number) {
        return hexToByte(intToHex(number));
    }

    public static byte[] toByteArray(int i) {
        byte[] array = new byte[4];
        array[3] = (byte) (i & 0xFF);
        array[2] = (byte) ((i >> 8) & 0xFF);
        array[1] = (byte) ((i >> 16) & 0xFF);
        array[0] = (byte) ((i >> 24) & 0xFF);
        return array;
    }

    public static byte[] hexStringToByteArray(String hexString) {
        int length = hexString.length();
        byte[] buffer = new byte[length / 2];
        for (int i = 0; i < length; i += 2) {
            //buffer[i / 2] = (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1)));
            buffer[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i+1), 16));
        }
        return buffer;
    }

    private static int toByte(char c) {
        if (c >= '0' && c <= '9')
            return (c - '0');
        if (c >= 'A' && c <= 'F')
            return (c - 'A' + 10);
        if (c >= 'a' && c <= 'f')
            return (c - 'a' + 10);
        throw new InvalidParameterException("Invalid hex char '" + c + "'");
    }
    /**
     * 将int转成hex字符串
     *
     * @param number
     * @return
     */
    public static String intToHex(int number) {
        String st = Integer.toHexString(number).toUpperCase();
        if (st.length()%2!=0){
            return String.format("0%s", st).replaceAll(" ", "0");
        }else {
            return String.format("%s", st).replaceAll(" ", "0");
        }
    }
    public static boolean isHexStringChineseChar(String hexString) {
        // 将16进制字符串转换为整数
        int codePoint = Integer.parseInt(hexString, 16);
        // 判断整数是否代表汉字
        return codePoint >= 0x4E00 && codePoint <= 0x9FFF;
    }
    public static String hexStringToOriginalString(String hexString) {
        if (hexString == null || hexString.length() % 2 != 0) {
            throw new IllegalArgumentException("Invalid hex string");
        }

        int length = hexString.length();
        ByteBuffer byteBuffer = ByteBuffer.allocate(length / 2);
        for (int i = 0; i < length; i += 2) {
            int value = Integer.parseInt(hexString.substring(i, i + 2), 16);
            byteBuffer.put((byte) value);
        }
        byteBuffer.flip();
        Charset charset = StandardCharsets.UTF_8; // 根据实际情况选择合适的字符集
        return charset.decode(byteBuffer).toString();
    }

    public static String originalStringToHexString(String originalString) {
        if (originalString == null) {
            throw new IllegalArgumentException("Invalid original string");
        }

        Charset charset = StandardCharsets.UTF_8; // 根据实际情况选择合适的字符集
        ByteBuffer byteBuffer = charset.encode(originalString);
        StringBuilder hexStringBuilder = new StringBuilder();
        while (byteBuffer.hasRemaining()) {
            byte b = byteBuffer.get();
            hexStringBuilder.append(String.format("%02x", b & 0xFF));
        }
        return hexStringBuilder.toString();
    }

    public static boolean isChineseCharacter(int codePoint) {

        // 常用汉字范围
        if (codePoint >= 0x4e00 && codePoint <= 0x9fa5) {
            return true;
        }
        // 扩展A
        if (codePoint >= 0x3400 && codePoint <= 0x4dbf) {
            return true;
        }
        // 扩展B
        if (codePoint >= 0x20000 && codePoint <= 0x2a6df) {
            return true;
        }
        // 扩展C
        if (codePoint >= 0x2a700 && codePoint <= 0x2b73f) {
            return true;
        }
        // 扩展D
        if (codePoint >= 0x2b740 && codePoint <= 0x2b81f) {
            return true;
        }
        // 扩展E
        if (codePoint >= 0x2b820 && codePoint <= 0x2ceaf) {
            return true;
        }
        // 扩展F
        if (codePoint >= 0x2ceb0 && codePoint <= 0x2ebef) {
            return true;
        }
        // 更多的扩展可以继续添加
        return false;
    }
    public static String intToHex(byte number) {
        String st = Integer.toHexString(number & 0x00ff).toUpperCase();
        if (st.length()%2!=0){
            return String.format("0%s", st).replaceAll(" ", "0");
        }else {
            return String.format("%s", st).replaceAll(" ", "0");
        }
    }


    /**
     * 字节转十进制
     *
     * @param b
     * @return
     */
    public static int byteToDec(byte b) {
        String s = byteToHex(b);
        return (int) hexToDec(s);
    }

    /**
     * 字节数组转十进制
     *
     * @param bytes
     * @return
     */
    public static int bytesToDec(byte[] bytes) {
        String s = encodeHexString(bytes);
        return (int) hexToDec(s);
    }

    /**
     * Hex字符串转int
     *
     * @param inHex
     * @return
     */
    public static int hexToInt(String inHex) {
        return Integer.parseInt(inHex, 16);
    }

    /**
     * 字节转十六进制字符串
     *
     * @param num
     * @return
     */
    public static String byteToHex(byte num) {
        char[] hexDigits = new char[2];
        hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16);
        hexDigits[1] = Character.forDigit((num & 0xF), 16);
        return new String(hexDigits).toUpperCase();
    }

    /**
     * 十六进制转byte字节
     *
     * @param hexString
     * @return
     */
    public static byte hexToByte(String hexString) {
        int firstDigit = toDigit(hexString.charAt(0));
        int secondDigit = toDigit(hexString.charAt(1));
        return (byte) ((firstDigit << 4) + secondDigit);
    }

    private static int toDigit(char hexChar) {
        int digit = Character.digit(hexChar, 16);
        if (digit == -1) {
            throw new IllegalArgumentException(
                    "Invalid Hexadecimal Character: " + hexChar);
        }
        return digit;
    }

    /**
     * 字节数组转十六进制
     *
     * @param byteArray
     * @return
     */
    public static String encodeHexString(byte[] byteArray) {
        StringBuffer hexStringBuffer = new StringBuffer();
        for (int i = 0; i < byteArray.length; i++) {
            hexStringBuffer.append(byteToHex(byteArray[i]));
        }
        return hexStringBuffer.toString().toUpperCase();
    }

    /**
     * 十六进制转字节数组
     *
     * @param hexString
     * @return
     */
    public static byte[] decodeHexString(String hexString) {
        if (hexString.length() % 2 == 1) {
            throw new IllegalArgumentException(
                    "Invalid hexadecimal String supplied.");
        }
        byte[] bytes = new byte[hexString.length() / 2];
        for (int i = 0; i < hexString.length(); i += 2) {
            bytes[i / 2] = hexToByte(hexString.substring(i, i + 2));
        }
        return bytes;
    }

    /**
     * 十进制转十六进制
     *
     * @param dec
     * @return
     */
    public static String decToHex(int dec) {
        String hex = Integer.toHexString(dec);
        if (hex.length() == 1) {
            hex = '0' + hex;
        }
        return hex.toUpperCase(Locale.CANADA);
    }

    /**
     * 十六进制转十进制
     *
     * @param hex
     * @return
     */
    public static long hexToDec(String hex) {
        return Long.parseLong(hex, 16);
    }

    /**
     * 十六进制转十进制，并对卡号补位
     */
    public static String setCardNum(String cardNun) {
        String cardNo1 = cardNun;
        String cardNo = null;
        if (cardNo1 != null) {
            Long cardNo2 = Long.parseLong(cardNo1, 16);
            //cardNo=String.format("%015d", cardNo2);
            cardNo = String.valueOf(cardNo2);
        }
        return cardNo;
    }
    public static float getByteToInt(byte[] bytes){
        int intValue = ((bytes[0] & 0x00ff) << 24) |
                ((bytes[1] & 0x00ff) << 16) |
                ((bytes[2] & 0x00ff) << 8) |
                (bytes[3] & 0x00ff);
        return Float.intBitsToFloat(intValue);
    }
    /** 16进制的字符串转换成16进制字符串数组
     * @param src
     * @return
     */
    public static byte[] HexString2Bytes(String src) {
        int len = src.length() / 2;
        byte[] ret = new byte[len];
        byte[] tmp = src.getBytes();
        for (int i = 0; i < len; i++) {
            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
        }
        return ret;
    }

    public static byte uniteBytes(byte src0, byte src1) {
        byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})).byteValue();
        _b0 = (byte) (_b0 << 4);
        byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})).byteValue();
        byte ret = (byte) (_b0 ^ _b1);
        return ret;
    }

    public static byte[] makeWriteDataCommand16(int registerAddr, int registerValue) {
        // 01 06 00 10 00 0F C8 0B
        char[] valueChar = new char[1];
        valueChar[0] = (char)(registerValue & 0x0000ffff);
        return makeWrite16bitRegDataCommand(registerAddr,valueChar);
    }


    public static byte[] makeWriteDataCommand(int registerAddr, int registerValue) {
        // 01 06 00 10 00 0F C8 0B
        char[] valueChar = new char[2];
        valueChar[0] = (char)(registerValue >> 16);
        valueChar[1] = (char)(registerValue & 0x0000ffff);
        return makeWrite16bitRegDataCommand(registerAddr,valueChar);
    }

    public static byte[] makeWriteFloatDataCommand(int registerStart,  float value) {
        //把float 转换为int数据
        char[] valueChar = new char[2];
        int floatToRawIntBits = Float.floatToRawIntBits(value);
        valueChar[0] = (char)(floatToRawIntBits >> 16);
        valueChar[1] = (char)(floatToRawIntBits & 0x0000ffff);
        return makeWrite16bitRegDataCommand(registerStart,valueChar);
    }

    /**
     *
     * @param code
     * @return
     */
    public static byte[] verifyCommand(byte[] code) {
        byte[] relist = new byte[2];
        int index= code.length-1;
        char crc =  HexCRCUtils.comp_crc16(code,index);
        relist[0] = (byte)(crc >> 8);                 //11       crc H
        relist[1] = (byte)(crc & 0x00ff);
        return relist;
    }

    //char --16bit
    public static byte[] makeWrite16bitRegDataCommand(int registerStart,char[] value) {
        // 01 10 0003 0001 04 40 86 66 66 EC2A
        byte[] relist = new byte[value.length +8];
        int index = 0;

        relist[index++] = (byte)0xAA;                       //0       地址
        relist[index++] = (byte)0x55;                       //1       命令码

        //relist[index++] = (byte)(registerStart >> 8);     //2       寄存器地址 H
        relist[index++] = (byte)(registerStart & 0x00ff);   //3       寄存器地址 H

        //int length = value.length;  //0010
        //relist[index++] = (byte)(length >> 8);            //4      寄存器长度 H
        //relist[index++] = (byte)(length & 0x00ff);        //5      寄存器长度 L

        relist[index++] = (byte)(value.length * 2);         //6      数据字节长度L

        for (int i = 0; i < value.length; i++) {
            relist[index++] = (byte)(value[i] >> 8);        //4      数据字节长度 H  AABB -> 00AA 8bit --> AA  1-> 10000

            relist[index++] = (byte)(value[i] & 0x00ff);    //5      数据字节长度 L  00BB ->      -------> BB
        }

        int crc =  HexCRCUtils.sumCRC(relist);
        //relist[index++] = (byte)(crc >> 8);               //11       crc H
        relist[index++] = (byte)(crc & 0x00ff);             //12       crc L

        relist[index++] = (byte)(0x0D);
        relist[index] = (byte)(0x0A);
        return relist;
    }


    public static byte[] makeWriteRegDataCommand(int registerStart,byte[] value) {
        // 01 10 0003 0001 04 40 86 66 66 EC2A
        byte[] relist = new byte[value.length +7];
        int index = 0;
        relist[index++] = (byte)0xAA;                       //0       地址
        relist[index++] = (byte)0x55;                       //1       命令码
        relist[index++] = (byte)(registerStart & 0x00ff);   //3       寄存器地址 H
        relist[index++] = (byte)(value.length);             //4      数据字节长度L
        for (int i = 0; i < value.length; i++) {
            relist[index++] = value[i];                     //5      数据字节长度 H  AABB -> 00AA 8bit --> AA  1-> 10000
        }
        int crc =  HexCRCUtils.sumCRC(relist);
        relist[index++] = (byte)(crc & 0x00ff);             //6       crc L
        relist[index++] = (byte)(0x0D);
        relist[index] = (byte)(0x0A);
        return relist;
    }

    public static byte[] makeWriteDataCommand(char registerAddr, char registerValue) {
        // 01 06 00 10 00 0F C8 0B
        byte[] relist = new byte[8];
        int index = 0;
        relist[index++] = (byte)0xAA;                     //0       地址
        relist[index++] = (byte)0x55;                      //1       命令码

        relist[index++] = (byte)(registerAddr >> 8);       //2       register H
        relist[index++] = (byte)(registerAddr & 0x00ff);   //3       register H

        relist[index++] = (byte)(registerValue >> 8);       //4       register V
        relist[index++] = (byte)(registerValue & 0x00ff);    //5       register V

        char crc =  HexCRCUtils.comp_crc16(relist,index -1);

        relist[index++] = (byte)(crc >> 8);                 //6       crc H
        relist[index] = (byte)(crc & 0x00ff);             //7       crc L

        return relist;
    }
    public static String hexToString(String hexString) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hexString.length(); i += 2) {
            String output = hexString.substring(i, (i + 2)); // 每两个16进制数字转换为一个字节
            int decimal = Integer.parseInt(output, 16); // 将16进制转换为十进制
            sb.append((char) decimal); // 将十进制转换成相应的字符
        }
        return sb.toString();
    }
}
